using System.Collections;
using System.Xml;

using LocalBoard.Domain;
using LocalBoard.Persistence;

using NUnit.Framework;

namespace LocalBoard.Controller
{
	[TestFixture]
	public class TestClubController
	{
		protected int _club1Id;
		protected int _club2Id;
		protected ClubController _unitUnderTest1;
		protected ClubController _unitUnderTest2;
		protected Profile _club1Manager;
		protected Profile _club2Manager;
		protected AdminController _adminController;
		protected int _user1Id;
		protected int _user2Id;

		[SetUp]
		public void setUp()
		{
			MockAccessorFactory accessorFactory = new MockAccessorFactory();
			IClubAccessor clubAccessor = accessorFactory.GetClubAccessor();
			IClubProfileAccessor clubProfileAccessor = accessorFactory.GetClubProfileAccessor();
			_adminController = new AdminController(accessorFactory);

			_user1Id = _adminController.CreateUser(new Profile("user1", "user1", "password", "test@test.com"));
			int managerId = _adminController.CreateUser(new Profile("manager", "manager", "password", "test@test.com"));
			_club1Manager = _adminController.GetUser(managerId);
			_club1Id = clubAccessor.Insert(new Club("test club1", "test club1", 1, "","", null));
			_unitUnderTest1 = new ClubController(_club1Id, accessorFactory);
			clubProfileAccessor.Insert(_club1Manager.Id, null, _club1Id);
			clubAccessor.AssignManagerToClub(_club1Manager.Id, _club1Id);

			_user2Id = _adminController.CreateUser(new Profile("user2", "user2", "password", "test@test.com"));
			managerId = _adminController.CreateUser(new Profile("manager2", "manager2", "password", "test@test.com"));
			_club2Manager = _adminController.GetUser(managerId);
			_club2Id = clubAccessor.Insert(new Club("test club2", "test club2", 1, "","", null));
			_unitUnderTest2 = new ClubController(_club2Id, accessorFactory);
			clubProfileAccessor.Insert(_club2Manager.Id, null, _club2Id);
			clubAccessor.AssignManagerToClub(_club2Manager.Id, _club2Id);
		}

		[TearDown]
		public void tearDown()
		{
			MockAccessorFactory.ResetDataTable();

			_unitUnderTest1 = null;
			_unitUnderTest2 = null;
			_club1Manager = null;
			_club2Manager = null;
			_adminController = null;
		}

		[Test]
		public void testAssignClubManager()
		{
			Assert.AreEqual(_club1Manager.Id, _unitUnderTest1.GetClubManager().Id);
			int userId = _adminController.CreateUser(new Profile("anotherUser1", "anotherUser1", "password", "test@test.com"));
			_unitUnderTest1.AssignClubManager(userId);
			Assert.AreEqual(userId, _unitUnderTest1.GetClubManager().Id);

			Assert.AreEqual(_club2Manager.Id, _unitUnderTest2.GetClubManager().Id);
			int user2Id = _adminController.CreateUser(new Profile("anotherUser2", "anotherUser2", "password", "test@test.com"));
			_unitUnderTest2.AssignClubManager(user2Id);
			Assert.AreEqual(user2Id, _unitUnderTest2.GetClubManager().Id);
		}

		[Test]
		public void testCreateBoard()
		{
			int returnVal = _unitUnderTest1.CreateBoard(new Board("test board1", null, 0, 0, _club1Id, BoardViewType.List));
			Assert.IsNotNull(_unitUnderTest1.GetBoard(returnVal));
			Assert.AreEqual("test board1", _unitUnderTest1.GetBoard(returnVal).Name);

			int returnVal2 = _unitUnderTest2.CreateBoard(new Board("test board2", null, 0, 0, _club2Id, BoardViewType.List));
			Assert.IsNotNull(_unitUnderTest2.GetBoard(returnVal2));
			Assert.AreEqual("test board2", _unitUnderTest2.GetBoard(returnVal2).Name);
		}

		[Test]
		public void testGetBoard()
		{
			int boardId = _unitUnderTest1.CreateBoard(new Board("test board", null, 0, 0, _club1Id, BoardViewType.List));
			Board returnBoard = _unitUnderTest1.GetBoard(boardId);
			Assert.IsNotNull(returnBoard);
			Assert.AreEqual("test board", returnBoard.Name);

			int boardId2 = _unitUnderTest2.CreateBoard(new Board("test board2", null, 0, 0, _club2Id, BoardViewType.List));
			Board returnBoard2 = _unitUnderTest2.GetBoard(boardId2);
			Assert.IsNotNull(returnBoard2);
			Assert.AreEqual("test board2", returnBoard2.Name);
		}

		[Test]
		public void testUpdateBoard()
		{
			int boardId = _unitUnderTest1.CreateBoard(new Board("test board", null, 0, 0, _club1Id, BoardViewType.List));
			Board returnBoard = _unitUnderTest1.GetBoard(boardId);
			returnBoard.Name = "test board updated";
			_unitUnderTest1.UpdateBoard(returnBoard);
			Assert.IsNotNull(_unitUnderTest1.GetBoard(boardId));
			Assert.AreEqual("test board updated", _unitUnderTest1.GetBoard(boardId).Name);

			int boardId2 = _unitUnderTest2.CreateBoard(new Board("test board2", null, 0, 0, _club2Id, BoardViewType.List));
			Board returnBoard2 = _unitUnderTest2.GetBoard(boardId2);
			returnBoard2.Name = "test board 2 updated";
			_unitUnderTest2.UpdateBoard(returnBoard2);
			Assert.IsNotNull(_unitUnderTest2.GetBoard(boardId2));
			Assert.AreEqual("test board 2 updated", _unitUnderTest2.GetBoard(boardId2).Name);
		}

		[Test]
		public void testDeleteBoard()
		{
			int boardId = _unitUnderTest1.CreateBoard(new Board("test board", null, 0, 0, _club1Id, BoardViewType.List));
			_unitUnderTest1.DeleteBoard(boardId);
			Assert.IsNull(_unitUnderTest1.GetBoard(boardId));

			int boardId2 = _unitUnderTest2.CreateBoard(new Board("test board2", null, 0, 0, _club2Id, BoardViewType.List));
			_unitUnderTest2.DeleteBoard(boardId2);
			Assert.IsNull(_unitUnderTest2.GetBoard(boardId2));
		}

		[Test]
		public void testGetBoardList()
		{
			int boardId1 = _unitUnderTest1.CreateBoard(new Board("test board5", null, 0, 0, _club1Id, BoardViewType.List));
			int boardId2 = _unitUnderTest1.CreateBoard(new Board("test board6", null, 0, 0, _club1Id, BoardViewType.List));
			ArrayList boardList = _unitUnderTest1.GetBoardList();
			Board board1 = _unitUnderTest1.GetBoard(boardId1);
			Board board2 = _unitUnderTest1.GetBoard(boardId2);
			bool foundBoard1 = false, foundBoard2 = false;
			foreach(Board board in boardList)
			{
				if(board.Name == board1.Name)
					foundBoard1 = true;
				else if(board.Name == board2.Name)
					foundBoard2 = true;
			}
			Assert.IsTrue(foundBoard1 && foundBoard2);

			int boardId21 = _unitUnderTest2.CreateBoard(new Board("test board21", null, 0, 0, _club2Id, BoardViewType.List));
			int boardId22 = _unitUnderTest2.CreateBoard(new Board("test board22", null, 0, 0, _club2Id, BoardViewType.List));
			ArrayList boardList2 = _unitUnderTest2.GetBoardList();
			Board board21 = _unitUnderTest2.GetBoard(boardId21);
			Board board22 = _unitUnderTest2.GetBoard(boardId22);
			bool foundBoard21 = false, foundBoard22 = false;
			foreach(Board board in boardList2)
			{
				if(board.Name == board21.Name)
					foundBoard21 = true;
				else if(board.Name == board22.Name)
					foundBoard22 = true;
			}
			Assert.IsTrue(foundBoard21 && foundBoard22);
		}

		[Test]
		public void testGetClubSecurity()
		{
			ClubSecurity returnVal = _unitUnderTest1.GetClubSecurity();
			Assert.IsNotNull(returnVal);

			ClubSecurity returnVal2 = _unitUnderTest2.GetClubSecurity();
			Assert.IsNotNull(returnVal2);

			Assert.IsTrue(returnVal != returnVal2);
		}

		[Test]
		public void testAssignClubRoleToUserAndIsUserInClubRole()
		{
			int clubRoleId = _unitUnderTest1.CreateClubRole("testRole1");
			_unitUnderTest1.AddUserClubProfile(null, _user1Id);
			_unitUnderTest1.AssignClubRoleToUser(clubRoleId, _user1Id);
			Assert.IsTrue(_unitUnderTest1.IsUserInClubRole(_user1Id, clubRoleId));

			int clubRoleId2 = _unitUnderTest2.CreateClubRole("testRole2");
			_unitUnderTest2.AddUserClubProfile(null, _user2Id);
			_unitUnderTest2.AssignClubRoleToUser(clubRoleId2, _user2Id);
			Assert.IsTrue(_unitUnderTest2.IsUserInClubRole(_user2Id, clubRoleId2));
		}

		[Test]
		public void testAddUserClubProfileAndIsUserInTheClubAndGetUserClubProfile()
		{
			XmlDocument doc1 = new XmlDocument();
			doc1.LoadXml("<profile><interests>sking</interests></profile>");
			_unitUnderTest1.AddUserClubProfile(doc1, _user1Id);
			Assert.IsTrue(_unitUnderTest1.IsUserInTheClub(_user1Id));
			XmlNode clubProfile1 = _unitUnderTest1.GetUserClubProfile(_user1Id);
			Assert.AreEqual("sking", clubProfile1.SelectSingleNode("//interests").InnerText);

			XmlDocument doc2 = new XmlDocument();
			doc2.LoadXml("<profile><interests>swimming</interests></profile>");
			_unitUnderTest2.AddUserClubProfile(doc2, _user2Id);
			Assert.IsTrue(_unitUnderTest2.IsUserInTheClub(_user2Id));
			XmlNode clubProfile2 = _unitUnderTest2.GetUserClubProfile(_user2Id);
			Assert.AreEqual("swimming", clubProfile2.SelectSingleNode("//interests").InnerText);
		}

		[Test]
		public void testUpdateUserClubProfile()
		{
			XmlDocument doc1 = new XmlDocument();
			doc1.LoadXml("<profile><interests>sking</interests></profile>");
			_unitUnderTest1.AddUserClubProfile(doc1, _user1Id);
			XmlDocument doc2 = new XmlDocument();
			doc2.LoadXml("<profile><interests>snowboarding</interests></profile>");
			_unitUnderTest1.UpdateUserClubProfile(doc2, _user1Id);
			XmlNode clubProfile = _unitUnderTest1.GetUserClubProfile(_user1Id);
			Assert.AreEqual("snowboarding", clubProfile.SelectSingleNode("//interests").InnerText);

			XmlDocument doc21 = new XmlDocument();
			doc21.LoadXml("<profile><interests>golfing</interests></profile>");
			_unitUnderTest2.AddUserClubProfile(doc21, _user2Id);
			XmlDocument doc22 = new XmlDocument();
			doc22.LoadXml("<profile><interests>yachting</interests></profile>");
			_unitUnderTest2.UpdateUserClubProfile(doc22, _user2Id);
			XmlNode clubProfile2 = _unitUnderTest2.GetUserClubProfile(_user2Id);
			Assert.AreEqual("yachting", clubProfile2.SelectSingleNode("//interests").InnerText);
		}
	}
}